home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / uucp / uulog / uulog.c < prev   
Encoding:
C/C++ Source or Header  |  1995-08-20  |  11.6 KB  |  493 lines

  1. /* uulog.c
  2.    Display the UUCP log file.
  3.  
  4.    Copyright (C) 1991, 1992, 1993, 1994, 1995 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #if USE_RCS_ID
  29. const char uulog_rcsid[] = "$Id: uulog.c,v 1.26 1995/06/29 19:37:19 ian Rel $";
  30. #endif
  31.  
  32. #include <ctype.h>
  33. #include <errno.h>
  34.  
  35. #include "getopt.h"
  36.  
  37. #include "uudefs.h"
  38. #include "uuconf.h"
  39. #include "system.h"
  40.  
  41. /* This is a pretty bad implementation of uulog, which I don't think
  42.    is a very useful program anyhow.  It only takes a single -s and/or
  43.    -u switch.  When using HAVE_HDB_LOGGING it requires a system.  */
  44.  
  45. /* Local functions.  */
  46.  
  47. static void ulusage P((void));
  48. static void ulhelp P((void));
  49.  
  50. /* Long getopt options.  */
  51. static const struct option asLlongopts[] =
  52. {
  53.   { "debuglog", no_argument, NULL, 'D' },
  54.   { "follow", optional_argument, NULL, 2 },
  55.   { "lines", required_argument, NULL, 'n' },
  56.   { "system", required_argument, NULL, 's' },
  57.   { "statslog", no_argument, NULL, 'S' },
  58.   { "user", required_argument, NULL, 'u' },
  59.   { "uuxqtlog", no_argument, NULL, 'x' },
  60.   { "config", required_argument, NULL, 'I' },
  61.   { "debug", required_argument, NULL, 'X' },
  62.   { "version", no_argument, NULL, 'v' },
  63.   { "help", no_argument, NULL, 1 },
  64.   { NULL, 0, NULL, 0 }
  65. };
  66.  
  67. int
  68. main (argc, argv)
  69.      int argc;
  70.      char **argv;
  71. {
  72.   /* -D: display Debug file */
  73.   boolean fdebug = FALSE;
  74.   /* -f: keep displaying lines forever.  */
  75.   boolean fforever = FALSE;
  76.   /* -n lines: number of lines to display.  */
  77.   int cshow = 0;
  78.   /* -s: system name.  */
  79.   const char *zsystem = NULL;
  80.   /* -S: display Stats file */
  81.   boolean fstats = FALSE;
  82.   /* -u: user name.  */
  83.   const char *zuser = NULL;
  84.   /* -I: configuration file name.  */
  85.   const char *zconfig = NULL;
  86.   /* -x: display uuxqt log file.  */
  87.   boolean fuuxqt = FALSE;
  88.   int i;
  89.   int iopt;
  90.   pointer puuconf;
  91.   int iuuconf;
  92.   const char *zlogfile;
  93.   const char *zstatsfile;
  94.   const char *zdebugfile;
  95.   const char *zfile;
  96.   FILE *e;
  97.   char **pzshow = NULL;
  98.   int ishow = 0;
  99.   size_t csystem = 0;
  100.   size_t cuser = 0;
  101.   char *zline;
  102.   size_t cline;
  103.  
  104.   zProgram = argv[0];
  105.  
  106.   /* Look for a straight number argument, and convert it to -n before
  107.      passing the arguments to getopt.  */
  108.   for (i = 0; i < argc; i++)
  109.     {
  110.       if (argv[i][0] == '-' && isdigit (argv[i][1]))
  111.     {
  112.       size_t clen;
  113.       char *znew;
  114.  
  115.       clen = strlen (argv[i]);
  116.       znew = zbufalc (clen + 2);
  117.       znew[0] = '-';
  118.       znew[1] = 'n';
  119.       memcpy (znew + 2, argv[i] + 1, clen);
  120.       argv[i] = znew;
  121.     }
  122.     }
  123.  
  124.   while ((iopt = getopt_long (argc, argv, "Df:FI:n:s:Su:vxX:", asLlongopts,
  125.                   (int *) NULL)) != EOF)
  126.     {
  127.       switch (iopt)
  128.     {
  129.     case 'D':
  130.       /* Show debugging file.  */
  131.       fdebug = TRUE;
  132.       break;
  133.  
  134.     case 'f':
  135.       /* Keep displaying lines forever for a particular system.  */
  136.       fforever = TRUE;
  137.       zsystem = optarg;
  138.       if (cshow == 0)
  139.         cshow = 10;
  140.       break;
  141.  
  142.     case 'F':
  143.       /* Keep displaying lines forever.  */
  144.       fforever = TRUE;
  145.       if (cshow == 0)
  146.         cshow = 10;
  147.       break;
  148.  
  149.     case 'I':
  150.       /* Configuration file name.  */
  151.       if (fsysdep_other_config (optarg))
  152.         zconfig = optarg;
  153.       break;
  154.  
  155.     case 'n':
  156.       /* Number of lines to display.  */
  157.       cshow = (int) strtol (optarg, (char **) NULL, 10);
  158.       break;
  159.  
  160.     case 's':
  161.       /* System name.  */
  162.       zsystem = optarg;
  163.       break;
  164.  
  165.     case 'S':
  166.       /* Show statistics file.  */
  167.       fstats = TRUE;
  168.       break;
  169.  
  170.     case 'u':
  171.       /* User name.  */
  172.       zuser = optarg;
  173.       break;
  174.  
  175.     case 'x':
  176.       /* Display uuxqt log file.  */
  177.       fuuxqt = TRUE;
  178.       break;
  179.  
  180.     case 'X':
  181. #if DEBUG > 1
  182.       /* Set debugging level.  */
  183.       iDebug |= idebug_parse (optarg);
  184. #endif
  185.       break;
  186.  
  187.     case 'v':
  188.       /* Print version and exit.  */
  189.       printf ("%s: Taylor UUCP %s, copyright (C) 1991, 92, 93, 94, 1995 Ian Lance Taylor\n",
  190.           zProgram, VERSION);
  191.       exit (EXIT_SUCCESS);
  192.       /*NOTREACHED*/
  193.  
  194.     case 2:
  195.       /* --follow.  */
  196.       fforever = TRUE;
  197.       if (cshow == 0)
  198.         cshow = 10;
  199.       if (optarg != NULL)
  200.         zsystem = optarg;
  201.       break;
  202.  
  203.     case 1:
  204.       /* --help.  */
  205.       ulhelp ();
  206.       exit (EXIT_SUCCESS);
  207.       /*NOTREACHED*/
  208.  
  209.     case 0:
  210.       /* Long option found and flag set.  */
  211.       break;
  212.  
  213.     default:
  214.       ulusage ();
  215.       /*NOTREACHED*/
  216.     }
  217.     }
  218.  
  219.   if (optind != argc || (fstats && fdebug))
  220.     ulusage ();
  221.  
  222.   iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig);
  223.   if (iuuconf != UUCONF_SUCCESS)
  224.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  225.  
  226. #if DEBUG > 1
  227.   {
  228.     const char *zdebug;
  229.  
  230.     iuuconf = uuconf_debuglevel (puuconf, &zdebug);
  231.     if (iuuconf != UUCONF_SUCCESS)
  232.       ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  233.     if (zdebug != NULL)
  234.       iDebug |= idebug_parse (zdebug);
  235.   }
  236. #endif
  237.  
  238.   iuuconf = uuconf_logfile (puuconf, &zlogfile);
  239.   if (iuuconf != UUCONF_SUCCESS)
  240.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  241.  
  242.   iuuconf = uuconf_statsfile (puuconf, &zstatsfile);
  243.   if (iuuconf != UUCONF_SUCCESS)
  244.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  245.  
  246.   iuuconf = uuconf_debugfile (puuconf, &zdebugfile);
  247.   if (iuuconf != UUCONF_SUCCESS)
  248.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  249.  
  250.   usysdep_initialize (puuconf, INIT_NOCHDIR);
  251.  
  252.   if (zsystem != NULL)
  253.     {
  254. #if HAVE_HDB_LOGGING
  255.       if (strcmp (zsystem, "ANY") != 0)
  256. #endif
  257.     {
  258.       struct uuconf_system ssys;
  259.  
  260.       /* Canonicalize the system name.  If we can't find the
  261.          system information, just use whatever we were given so
  262.          that people can check on systems that logged in
  263.          anonymously.  */
  264.       iuuconf = uuconf_system_info (puuconf, zsystem, &ssys);
  265.       if (iuuconf == UUCONF_SUCCESS)
  266.         {
  267.           zsystem = zbufcpy (ssys.uuconf_zname);
  268.           (void) uuconf_system_free (puuconf, &ssys);
  269.         }
  270.     }
  271.     }
  272.  
  273.   if (fstats)
  274.     zfile = zstatsfile;
  275.   else if (fdebug)
  276.     zfile = zdebugfile;
  277.   else
  278.     {
  279. #if ! HAVE_HDB_LOGGING
  280.       zfile = zlogfile;
  281. #else
  282.       const char *zprogram;
  283.       char *zalc;
  284.  
  285.       /* We need a system to find a HDB log file.  */
  286.       if (zsystem == NULL)
  287.     ulog (LOG_FATAL,
  288.           "system name (-s argument) required for HDB format log files");
  289.  
  290.       if (fuuxqt)
  291.     zprogram = "uuxqt";
  292.       else
  293.     zprogram = "uucico";
  294.  
  295.       zalc = zbufalc (strlen (zlogfile)
  296.               + strlen (zprogram)
  297.               + strlen (zsystem)
  298.               + 1);
  299.       sprintf (zalc, zlogfile, zprogram, zsystem);
  300.       zfile = zalc;
  301.  
  302.       if (! fsysdep_file_exists (zfile))
  303.     ulog (LOG_FATAL, "no log file available for system %s", zsystem);
  304.  
  305.       if (strcmp (zsystem, "ANY") == 0)
  306.     zsystem = NULL;
  307. #endif
  308.     }
  309.  
  310.   e = fopen (zfile, "r");
  311.   if (e == NULL)
  312.     {
  313.       ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno));
  314.       usysdep_exit (FALSE);
  315.     }
  316.  
  317.   if (cshow > 0)
  318.     {
  319.       pzshow = (char **) xmalloc (cshow * sizeof (char *));
  320.       for (ishow = 0; ishow < cshow; ishow++)
  321.     pzshow[ishow] = NULL;
  322.       ishow = 0;
  323.     }
  324.  
  325.   /* Read the log file and output the appropriate lines.  */
  326.   if (zsystem != NULL)
  327.     csystem = strlen (zsystem);
  328.  
  329.   if (zuser != NULL)
  330.     cuser = strlen (zuser);
  331.  
  332.   zline = NULL;
  333.   cline = 0;
  334.  
  335.   while (TRUE)
  336.     {
  337.       while (getline (&zline, &cline, e) > 0)
  338.     {
  339.       char *zluser, *zlsys, *znext;
  340.       size_t cluser, clsys;
  341.  
  342.       /* Skip any leading whitespace (not that there should be
  343.          any).  */
  344.       znext = zline + strspn (zline, " \t");
  345.  
  346.       if (! fstats)
  347.         {
  348. #if ! HAVE_TAYLOR_LOGGING
  349.           /* The user name is the first field on the line.  */
  350.           zluser = znext;
  351.           cluser = strcspn (znext, " \t");
  352. #endif
  353.       
  354.           /* Skip the first field.  */
  355.           znext += strcspn (znext, " \t");
  356.           znext += strspn (znext, " \t");
  357.  
  358.           /* The system is the second field on the line.  */
  359.           zlsys = znext;
  360.           clsys = strcspn (znext, " \t");
  361.  
  362.           /* Skip the second field.  */
  363.           znext += clsys;
  364.           znext += strspn (znext, " \t");
  365.  
  366. #if HAVE_TAYLOR_LOGGING
  367.           /* The user is the third field on the line.  */
  368.           zluser = znext;
  369.           cluser = strcspn (znext, " \t");
  370. #endif
  371.         }
  372.       else
  373.         {
  374. #if ! HAVE_HDB_LOGGING
  375.           /* The user name is the first field on the line, and the
  376.          system name is the second.  */
  377.           zluser = znext;
  378.           cluser = strcspn (znext, " \t");
  379.           znext += cluser;
  380.           znext += strspn (znext, " \t");
  381.           zlsys = znext;
  382.           clsys = strcspn (znext, " \t");
  383. #else
  384.           /* The first field is system!user.  */
  385.           zlsys = znext;
  386.           clsys = strcspn (znext, "!");
  387.           znext += clsys + 1;
  388.           zluser = znext;
  389.           cluser = strcspn (znext, " \t");
  390. #endif
  391.         }
  392.  
  393.       /* See if we should print this line.  */
  394.       if (zsystem != NULL
  395.           && (csystem != clsys
  396.           || strncmp (zsystem, zlsys, clsys) != 0))
  397.         continue;
  398.  
  399.       if (zuser != NULL
  400.           && (cuser != cluser
  401.           || strncmp (zuser, zluser, cluser) != 0))
  402.         continue;
  403.  
  404.       /* Output the line, or save it if we are outputting only a
  405.          particular number of lines.  */
  406.       if (cshow <= 0)
  407.         printf ("%s", zline);
  408.       else
  409.         {
  410.           ubuffree ((pointer) pzshow[ishow]);
  411.           pzshow[ishow] = zbufcpy (zline);
  412.           ishow = (ishow + 1) % cshow;
  413.         }
  414.     }
  415.  
  416.       /* Output the number of lines requested by the -n option.  */
  417.       if (cshow > 0)
  418.     {
  419.       for (i = 0; i < cshow; i++)
  420.         {
  421.           if (pzshow[ishow] != NULL)
  422.         printf ("%s", pzshow[ishow]);
  423.           ishow = (ishow + 1) % cshow;
  424.         }
  425.     }
  426.  
  427.       /* If -f was not specified, or an error occurred while reading
  428.      the file, get out.  */
  429.       if (! fforever || ferror (e))
  430.     break;
  431.  
  432.       clearerr (e);
  433.       cshow = 0;
  434.  
  435.       /* Sleep 1 second before going around the loop again.  */
  436.       usysdep_sleep (1);
  437.     }
  438.  
  439.   (void) fclose (e);
  440.  
  441.   ulog_close ();
  442.  
  443.   usysdep_exit (TRUE);
  444.  
  445.   /* Avoid errors about not returning a value.  */
  446.   return 0;
  447. }
  448.  
  449. /* Print a usage message and die.  */
  450.  
  451. static void
  452. ulusage ()
  453. {
  454.   fprintf (stderr,
  455.        "Usage: %s [-n #] [-sf system] [-u user] [-xDSF] [-I file] [-X debug]\n",
  456.        zProgram);
  457.   fprintf (stderr, "Use %s --help for help\n", zProgram);
  458.   exit (EXIT_FAILURE);
  459. }
  460.  
  461. /* Print a help message.  */
  462.  
  463. static void
  464. ulhelp ()
  465. {
  466.   printf ("Taylor UUCP %s, copyright (C) 1991, 92, 93, 94, 1995 Ian Lance Taylor\n",
  467.        VERSION);
  468. #if HAVE_HDB_LOGGING
  469.   printf ("Usage: %s [-n #] [-sf system] [-u user] [-xDS] [-I file] [-X debug]\n",
  470.        zProgram);
  471. #else
  472.   printf ("Usage: %s [-n #] [-sf system] [-u user] [-DSF] [-I file] [-X debug]\n",
  473.        zProgram);
  474. #endif
  475.   printf (" -n,--lines: show given number of lines from end of log\n");
  476.   printf (" -s,--system: print entries for named system\n");
  477.   printf (" -f system,--follow=system: follow entries for named system\n");
  478.   printf (" -u,--user user: print entries for named user\n");
  479. #if HAVE_HDB_LOGGING
  480.   printf (" -x,--uuxqt: print uuxqt log rather than uucico log\n");
  481. #else
  482.   printf (" -F,--follow: follow entries for any system\n");
  483. #endif
  484.   printf (" -S,--statslog: show statistics file\n");
  485.   printf (" -D,--debuglog: show debugging file\n");
  486.   printf (" -X,--debug debug: Set debugging level\n");
  487. #if HAVE_TAYLOR_CONFIG
  488.   printf (" -I,--config file: Set configuration file to use\n");
  489. #endif /* HAVE_TAYLOR_CONFIG */
  490.   printf (" -v,--version: Print version and exit\n");
  491.   printf (" --help: Print help and exit\n");
  492. }
  493.